package com.ruoyi.cs.service.impl;

import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Response;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.cs.domain.*;
import com.ruoyi.cs.domain.vo.TRedbagVo;
import com.ruoyi.cs.mapper.*;
import com.ruoyi.cs.service.ITRedbagService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.xml.soap.SAAJResult;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * 红包信息Service业务层处理
 * 
 * @author ruoyi
 * @date 2021-03-25
 */
@Service
@SuppressWarnings("all")
public class TRedbagServiceImpl implements ITRedbagService
{
    @Autowired
    private TRedbagMapper tRedbagMapper;
    @Autowired
    private TUserMapper tUserMapper;
    @Autowired
    private TRedbagOpenMapper tRedbagOpenMapper;
    @Autowired
    private TRechargeMapper tRechargeMapper;
    @Autowired
    private TUserTgMapper tUserTgMapper;
    @Autowired
    private TBalanceChangeMapper tBalanceChangeMapper;

    /**
     * 查询红包信息
     * 
     * @param redbagId 红包信息ID
     * @return 红包信息
     */
    @Override
    public TRedbag selectTRedbagById(String redbagId)
    {
        return tRedbagMapper.selectTRedbagById(redbagId);
    }

    /**
     * 查询红包信息列表
     * 
     * @param tRedbag 红包信息
     * @return 红包信息
     */
    @Override
    public List<TRedbag> selectTRedbagList(TRedbag tRedbag)
    {
        return tRedbagMapper.selectTRedbagListBack(tRedbag);
    }

    /**
     * 新增红包信息
     * 
     * @param tRedbag 红包信息
     * @return 结果
     */
    @Override
    public Response insertTRedbag(TRedbag tRedbag)
    {
        if ((tRedbag.getMinAmount() != null && tRedbag.getMaxAmount() == null) || (tRedbag.getMinAmount() == null && tRedbag.getMaxAmount() != null)){
            return  Response.fail(Constants.FAILCODE,"随机金额红包最小最大金额必须同时填写或者同时不填！");
        }else if(tRedbag.getMinAmount() != null && tRedbag.getMaxAmount() != null && tRedbag.getMinAmount().compareTo(tRedbag.getMaxAmount()) >= 0){
            Response.fail(Constants.FAILCODE,"随机金额红包最小值不能大于等于最大值！");
        }
        /**规则校验*/
        if (StringUtils.isEmpty(tRedbag.getRedbagType())) {
            return  Response.fail(Constants.FAILCODE,"红包类型不能为空！");
        }
        if (StringUtils.isEmpty(tRedbag.getRedbagName())) {
            return  Response.fail(Constants.FAILCODE,"红包名称不能为空！！");
        }
        if (StringUtils.isNull(tRedbag.getGroundingNum()) || tRedbag.getGroundingNum() < 1) {
            return  Response.fail(Constants.FAILCODE,"上架红包数量不能为空且大于0！");
        }
        if (StringUtils.isNull(tRedbag.getCutoffTime())) {
            return  Response.fail(Constants.FAILCODE,"红包截止时间不能为空！");
        }
        if (tRedbag.getCutoffTime().getTime() < DateUtils.getNowDate().getTime()) {
            return  Response.fail(Constants.FAILCODE,"红包截止时间必须大于当前时间！");
        }
        if (StringUtils.isNull(tRedbag.getRedbagMoney()) || tRedbag.getRedbagMoney().doubleValue() <= 0) {
            return  Response.fail(Constants.FAILCODE,"红包金额不能为空并且大于0！");
        }
        if(tRedbag.getRedbagType().equals(Constants.REDBAGTYPE4)){
            if(StringUtils.isEmpty(tRedbag.getAppointPhoneNum())){
                return  Response.fail(Constants.FAILCODE,"指定手机号码不能为空！");
            }
            TUser userInfoByPhone = tUserMapper.getUserInfoByPhone(tRedbag.getAppointPhoneNum());
            if(userInfoByPhone == null){
                return  Response.fail(Constants.FAILCODE,"不存在指定手机号码的账户！");
            }
            tRedbag.setRedbagTotalnum(1L);
        }
        if (StringUtils.isNotEmpty(tRedbag.getRedbagCode()))
        {
            if (!(tRedbag.getRedbagCode().length()>=2 &&tRedbag.getRedbagCode().length()<=16)) {
                return Response.fail(Constants.FAILCODE,"红包口令字符长度限制在2-16位！");
            }
            TRedbag tRedbag1 = tRedbagMapper.getRedBagInfoByCode(tRedbag.getRedbagCode());
            if (tRedbag1 != null) {
                return Response.fail(Constants.FAILCODE,"红包口令重复！");
            }
        }
        tRedbag.setRedbagOvernum(tRedbag.getGroundingNum());
        tRedbag.setRedbagTotalnum(tRedbag.getGroundingNum());
        if (tRedbag.getRedbagType().equals(Constants.REDBAGTYPE1)) {
                if (StringUtils.isNotEmpty(tRedbag.getUserCode())) {
                    TUser tUser = tUserMapper.getUserInfoByCode(tRedbag.getUserCode());
                    if (tUser == null || !tUser.getDelFlag().equals(Constants.SUCCESS)) {
                        return Response.fail(Constants.FAILCODE,"推广码错误！");
                    }
                }else {
                    return Response.fail(Constants.FAILCODE,"推广码不能为空！");
                }
        }else if (tRedbag.getRedbagType().equals(Constants.REDBAGTYPE3)) {
            if (StringUtils.isNull(tRedbag.getRedbagMoney()) || StringUtils.isNull(tRedbag.getRechargeStartTime()) || StringUtils.isNull(tRedbag.getRechargeEndTime())) {
                return Response.fail(Constants.FAILCODE,"充值金额、充值门槛时间不能为空！");
            }
        }
        tRedbag.setDelFlag(Constants.SUCCESS);
        tRedbag.setRedbagCode(StringUtils.isNotEmpty(tRedbag.getRedbagCode()) ? tRedbag.getRedbagCode() : IdUtils.fastUUID().substring(0,8));
        tRedbag.setCreateTime(DateUtils.getNowDate());
        tRedbagMapper.insertTRedbag(tRedbag);
        return Response.success();
    }

    /**
     * 修改红包信息
     * 
     * @param tRedbag 红包信息
     * @return 结果
     */
    @Override
    public Response updateTRedbag(TRedbag tRedbag)
    {
        if ((tRedbag.getMinAmount() != null && tRedbag.getMaxAmount() == null) || (tRedbag.getMinAmount() == null && tRedbag.getMaxAmount() != null)){
            return  Response.fail(Constants.FAILCODE,"随机金额红包最小最大金额必须同时填写或者同时不填！");
        }else if(tRedbag.getMinAmount() != null && tRedbag.getMaxAmount() != null && tRedbag.getMinAmount().compareTo(tRedbag.getMaxAmount()) >= 0){
            Response.fail(Constants.FAILCODE,"随机金额红包最小值不能大于最大值！");
        }
        /**规则校验*/
        if (StringUtils.isEmpty(tRedbag.getRedbagType())) {
            return Response.fail(Constants.FAILCODE,"红包类型不能为空！");
        }
        if (tRedbag.getRedbagName().equals(Constants.REDBAGTYPE4)) {
            return Response.fail(Constants.FAILCODE,"当前红包不支持修改！");
        }
        if (StringUtils.isEmpty(tRedbag.getRedbagName())) {
            return Response.fail(Constants.FAILCODE,"红包名称不能为空！！");
        }
        if (StringUtils.isNull(tRedbag.getRedbagMoney()) || tRedbag.getRedbagMoney().doubleValue() <= 0) {
            return  Response.fail(Constants.FAILCODE,"红包金额不能为空并且大于0！");
        }
        /*if (StringUtils.isNull(tRedbag.getGroundingNum())) {
            return Response.fail(Constants.FAILCODE,"上架红包数量不能为空！");
        }*/
        if (StringUtils.isNull(tRedbag.getCutoffTime())) {
            return Response.fail(Constants.FAILCODE,"红包截止时间不能为空！");
        }
        if (tRedbag.getCutoffTime().getTime() < DateUtils.getNowDate().getTime()) {
            return Response.fail(Constants.FAILCODE,"红包截止时间必须大于当前时间！");
        }
        long groundingNum = tRedbag.getGroundingNum() == null ? 0l : tRedbag.getGroundingNum();
        long redbagOvernum = tRedbag.getRedbagOvernum() == null ? 0l : tRedbag.getRedbagOvernum();
        long redbagTotalnum = tRedbag.getRedbagTotalnum() == null ? 0l : tRedbag.getRedbagTotalnum();
        tRedbag.setRedbagOvernum(groundingNum+redbagOvernum);
        tRedbag.setRedbagTotalnum(groundingNum+redbagTotalnum);
        if(tRedbag.getRedbagType().equals(Constants.REDBAGTYPE0)){
            /*如果是普通红包，清空推广码、充值门槛时间、充值金额*/
            tRedbag.setUserCode(null);
            tRedbag.setRechargeStartTime(null);
            tRedbag.setRechargeEndTime(null);
            tRedbag.setRechargeAmount(new BigDecimal(0));
        }else if (tRedbag.getRedbagType().equals(Constants.REDBAGTYPE1) ) {
            if (StringUtils.isNotEmpty(tRedbag.getUserCode())) {
                TUser tUser = tUserMapper.getUserInfoByCode(tRedbag.getUserCode());
                if (tUser == null || !tUser.getDelFlag().equals(Constants.SUCCESS)) {
                    return Response.fail(Constants.FAILCODE,"推广码错误！");
                }
            }else {
                return Response.fail(Constants.FAILCODE,"推广码不能为空！");
            }
            tRedbag.setRechargeStartTime(null);
            tRedbag.setRechargeEndTime(null);
            tRedbag.setRechargeAmount(new BigDecimal(0));
        }else if (tRedbag.getRedbagType().equals(Constants.REDBAGTYPE3)) {
            if (StringUtils.isNull(tRedbag.getRedbagMoney()) || StringUtils.isNull(tRedbag.getRechargeStartTime()) || StringUtils.isNull(tRedbag.getRechargeEndTime())) {
                return Response.fail(Constants.FAILCODE,"充值金额、充值门槛时间不能为空！");
            }
            tRedbag.setUserCode(null);
        }else {
            tRedbag.setUserCode(null);
            tRedbag.setRechargeStartTime(null);
            tRedbag.setRechargeEndTime(null);
        }
        tRedbag.setUpdateTime(DateUtils.getNowDate());
        tRedbagMapper.updateTRedbag1(tRedbag);
        return Response.success();
    }

    /**
     * 批量删除红包信息
     * 
     * @param redbagIds 需要删除的红包信息ID
     * @return 结果
     */
    @Override
    public int deleteTRedbagByIds(String[] redbagIds)
    {
        return tRedbagMapper.logicDeleteTRedbagByIds(redbagIds);
    }

    /**
     * 删除红包信息信息
     * 
     * @param redbagId 红包信息ID
     * @return 结果
     */
    @Override
    public int deleteTRedbagById(String redbagId)
    {
        return tRedbagMapper.deleteTRedbagById(redbagId);
    }

    /**
     * 领取红包
     * @param userId
     * @param redbagCode
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response<TRedbag> receiveRedbag(String userId, String redbagCode) throws Exception {
        /**获取用户信息*/
        TUser tUser = tUserMapper.selectTUserById(userId);
        if (tUser == null) {
            return Response.fail(Constants.FAILCODE,"用户不存在！");
        }
        /**获取红包信息*/
        TRedbag tRedbag =  tRedbagMapper.getRedBagInfoByCode(redbagCode);
        if (tRedbag == null) {
            return Response.fail(Constants.FAILCODE,"红包口令错误！");
        }
        if (tRedbag.getCutoffTime().getTime() < DateUtils.getNowDate().getTime()) {
            return Response.fail(Constants.FAILCODE,"红包已过期！");
        }
        if (tRedbag.getRedbagOvernum() <= 0) {
            return Response.fail(Constants.FAILCODE,"红包已被领完！");
        }
        /**判断该用户是否领取过此红包*/
        TRedbagOpen open = new TRedbagOpen();
        open.setUserId(userId);
        open.setRedbagCode(redbagCode);
        List<TRedbagOpen> openList = tRedbagOpenMapper.selectTRedbagOpenList(open);
        if (openList.size()>0) {
            return Response.fail(Constants.FAILCODE,"已领取过此红包，不能重复领取！");
        }

        /**获取红包类型,判断用户是否能领取红包 */
        /**0 普通红包:都能领取
         * 1 拉新红包：没有填写过推广码的 或者填写是次邀请码的
         * 2 历史充值门槛红包：达到充值门槛才能领取
         * 3 时间段充值门槛：时间段内达到充值门槛才能领取*/

        String type = tRedbag.getRedbagType();
        boolean flag = false;
        boolean tgflag = false;
        if (type.equals(Constants.REDBAGTYPE0)) {
            flag = true;
        } else if (type.equals(Constants.REDBAGTYPE1)) {
            /**判断是否领取过拉新红包*/
            Long num = tRedbagOpenMapper.countLXHBNum(userId);
            if(num > 0){
                return Response.fail(Constants.FAILCODE, "已领取过拉新红包，不可重复领取！");
            }

            if (StringUtils.isEmpty(tUser.getUserPromotersId())) {
                flag = true;
                TUser tgUser = tUserMapper.getUserInfoByCode(tRedbag.getUserCode());
                if (tUser.getUserSelfCode().equals(tRedbag.getUserCode())) {
                    return Response.fail(Constants.FAILCODE, "暂不符合领取条件！");
                }
                tUser.setUserPromotersId(tgUser.getUserId());
                tgflag = true;
            } else {
                TUser tgUser = tUserMapper.selectTUserById(tUser.getUserPromotersId());
                if (tgUser.getUserSelfCode().equals(tRedbag.getUserCode())) {
                    flag = true;
                }else {
                    return Response.fail(Constants.FAILCODE, "暂不符合领取条件!");
                }
            }
        } else if (type.equals(Constants.REDBAGTYPE2)) {
            //BigDecimal czMoney = tRechargeMapper.czMoneyCountByUserId(tUser.getUserId(), null, null);
            BigDecimal czMoney = tUser.getUserTotalRecharge();
            if (czMoney != null && czMoney.compareTo(tRedbag.getRechargeAmount()) >= 0) {
                flag = true;
            }
        } else if (type.equals(Constants.REDBAGTYPE3)) {
            BigDecimal czMoney = tRechargeMapper.czMoneyCountByUserId(tUser.getUserId(), tRedbag.getRechargeStartTime(), tRedbag.getRechargeEndTime());
            if (czMoney != null && czMoney.compareTo(tRedbag.getRechargeAmount()) >= 0) {
                flag = true;
            }
        } else if (type.equals(Constants.REDBAGTYPE4)) {
            if (tUser.getUserPhone().equals(tRedbag.getAppointPhoneNum())) {
                flag = true;
            }
        }

        if (flag) {
            TRedbagOpen tRedbagOpen = new TRedbagOpen();
            tRedbagOpen.setRedbagId(tRedbag.getRedbagId());
            tRedbagOpen.setUserId(tUser.getUserId());
            tRedbagOpen.setRedbagCode(tRedbag.getRedbagCode());

            /**判断是否是随机红包*/
            BigDecimal redbagFee = null;
            if(tRedbag.getMinAmount() != null && tRedbag.getMaxAmount() != null){
                BigDecimal rangeMinMoney = tRedbag.getMinAmount().compareTo(new BigDecimal(0)) == 0 ? new BigDecimal(1) : tRedbag.getMinAmount().multiply(new BigDecimal(100));
                BigDecimal rangeMaxMoney = tRedbag.getMaxAmount().multiply(new BigDecimal(100));
                Random random = new Random();
                int price = random.nextInt(rangeMaxMoney.intValue())%(rangeMaxMoney.intValue()-rangeMinMoney.intValue()+1) + rangeMinMoney.intValue();
                redbagFee = new BigDecimal(price).divide(new BigDecimal(100)).setScale(2,BigDecimal.ROUND_HALF_UP);
            }else {
                redbagFee = tRedbag.getRedbagMoney();
            }
            tRedbagOpen.setRedbagMoney(redbagFee);

            tRedbagOpen.setCreateTime(DateUtils.getNowDate());
            tRedbagOpenMapper.insertTRedbagOpen(tRedbagOpen);
            tRedbag.setRedbagOvernum(tRedbag.getRedbagOvernum() - 1);
            int redbagUpdataCount = tRedbagMapper.updateTRedbag(tRedbag);
            if (redbagUpdataCount == 0) {
                throw new SQLException("红包信息修改错误！");
            }

            TBalanceChange balanceChange = new TBalanceChange();
            balanceChange.setOperationType(Constants.OPERATIONTYPE4);
            balanceChange.setBalanceBefore(tUser.getUserBalance());
            balanceChange.setBalanceAfter(tUser.getUserBalance().add(redbagFee));
            balanceChange.setFrequency(1);
            balanceChange.setCorrespondingid(tRedbag.getRedbagId());
            balanceChange.setUserId(tUser.getUserId());
            balanceChange.setFee(redbagFee);
            balanceChange.setCreateTime(new Date());
            balanceChange.setSecondCurrencyBefore(tUser.getSecondCurrency());
            balanceChange.setSecondCurrencyAfter(tUser.getSecondCurrency());
            balanceChange.setConsumeValue(BigDecimal.ZERO);
            balanceChange.setProfitPrice(redbagFee);
            balanceChange.setCostFee(BigDecimal.ZERO);
            tBalanceChangeMapper.insertTBalanceChange(balanceChange);


            tUser.setUpdateTime(DateUtils.getNowDate());
            tUser.setUserBalance(tUser.getUserBalance().add(redbagFee));
            if (tgflag) {
                TUserTg tg = new TUserTg();
                TUser tgUser = tUserMapper.getUserInfoByCode(tRedbag.getUserCode());
                tg.setUserId(tgUser.getUserId());
                tg.setTgUserId(userId);
                tg.setCreateTime(DateUtils.getNowDate());
                tUserTgMapper.insertTUserTg(tg);

                tUser.setSjUserId(tgUser.getUserId());
            }
            int count = tUserMapper.updateTUserBalance(tUser);
            if (count == 0) {
                throw new SQLException("用户账户修改错误！");
            }
            tRedbag.setRedbagMoney(redbagFee);
            return Response.success(tRedbag);
        }else {
            return Response.fail(Constants.FAILCODE,"暂不符合领取条件！");
        }
    }

    /**
     * 通过红包口令获取红包信息
     * @param redbagCode
     * @return
     */
    @Override
    public TRedbag getRedBagInfoByCode(String redbagCode) {
        return tRedbagMapper.getRedBagInfoByCode(redbagCode);
    }

    /**
     * 红包领取记录列表
     * @param tRedbagVo
     * @return
     */
    @Override
    public List<TRedbagVo> receiveRecode(TRedbagVo tRedbagVo) {
        return tRedbagMapper.receiveRecode(tRedbagVo);
    }

    @Override
    public List<TRedbagVo> selectShowRedbagList(String userId) {
        /*查询出所有展示红包列表*/
        List<TRedbagVo> tRedbagList = tRedbagMapper.selectShowRedbagList();
        List<String> redbagIdList = tRedbagList.stream().map(TRedbagVo::getRedbagId).collect(Collectors.toList());
        if (redbagIdList.size() > 0) {
            TUser tUser = null;
            if (StringUtils.isNotEmpty(userId)) {
                /**获取用户信息*/
                tUser = tUserMapper.selectTUserById(userId);
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            /*查询出当前用户已领取的列表*/
            List<String> receiveRecord = tRedbagOpenMapper.selectReceiveRecord(userId, redbagIdList);
            for (TRedbagVo bean : tRedbagList) {
                if (receiveRecord.contains(bean.getRedbagId())) {
                    bean.setIsReceive(Constants.SUCCESS);
                } else {
                    bean.setIsReceive(Constants.FAIL);
                }
                /*历史充值门槛*/
                if (Constants.REDBAGTYPE2.equals(bean.getRedbagType())) {
                    if (tUser != null && tUser.getUserTotalRecharge().compareTo(bean.getRechargeAmount()) >= 0) {
                        bean.setEligibility(Constants.SUCCESS);
                    } else {
                        bean.setEligibility(Constants.FAIL);
                    }
                }
                if (Constants.REDBAGTYPE3.equals(bean.getRedbagType())) {
                    if (tUser != null) {
                        BigDecimal czMoney = tRechargeMapper.czMoneyCountByUserId(tUser.getUserId(), bean.getRechargeStartTime(), bean.getRechargeEndTime());
                        if (czMoney != null && czMoney.compareTo(bean.getRechargeAmount()) >= 0) {
                            bean.setEligibility(Constants.SUCCESS);
                        } else {
                            bean.setEligibility(Constants.FAIL);
                        }
                    } else {
                        bean.setEligibility(Constants.FAIL);
                    }
                }
            }
        }
        return tRedbagList;
    }
}
